{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 数据预处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/malele/anaconda3/lib/python3.6/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
      "  from ._conv import register_converters as _register_converters\n",
      "Using TensorFlow backend.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "X_train shape: (13341, 200, 12, 1)\n",
      "Y_train shape: (13341, 49)\n",
      "X_test shape: (3335, 200, 12, 1)\n",
      "Y_test shape: (3335, 49)\n"
     ]
    }
   ],
   "source": [
    "import h5py\n",
    "import numpy as np\n",
    "import tensorflow as tf \n",
    "import keras\n",
    "from keras.layers import Input, Dense, ZeroPadding2D, Dropout, Activation, BatchNormalization, Flatten, Conv2D, AveragePooling2D, MaxPooling2D\n",
    "from keras.models import Model\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "def convert_to_one_hot(Y, C):\n",
    "    Y = np.eye(C)[Y.reshape(-1)].T\n",
    "    return Y\n",
    "\n",
    "file = h5py.File('DB2/DB2_S4_image_200_0.h5','r')\n",
    "imageData   = file['imageData'][:]\n",
    "imageLabel  = file['imageLabel'][:]  \n",
    "file.close()\n",
    "\n",
    "# 随机打乱数据和标签\n",
    "N = imageData.shape[0]\n",
    "index = np.random.permutation(N)\n",
    "data  = imageData[index,:,:]\n",
    "label = imageLabel[index]\n",
    "\n",
    "# 对数据升维,标签one-hot\n",
    "data  = np.expand_dims(data, axis=3)\n",
    "label = convert_to_one_hot(label,49).T\n",
    "\n",
    "# 划分数据集\n",
    "N = data.shape[0]\n",
    "num_train = round(N*0.8)\n",
    "X_train = data[0:num_train,:,:,:]\n",
    "Y_train = label[0:num_train,:]\n",
    "X_test  = data[num_train:N,:,:,:]\n",
    "Y_test  = label[num_train:N,:]\n",
    "\n",
    "print (\"X_train shape: \" + str(X_train.shape))\n",
    "print (\"Y_train shape: \" + str(Y_train.shape))\n",
    "print (\"X_test shape: \" + str(X_test.shape))\n",
    "print (\"Y_test shape: \" + str(Y_test.shape))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "#写一个LossHistory类，保存loss和acc\n",
    "class LossHistory(keras.callbacks.Callback):\n",
    "    def on_train_begin(self, logs={}):\n",
    "        self.losses = {'batch':[], 'epoch':[]}\n",
    "        self.accuracy = {'batch':[], 'epoch':[]}\n",
    "        self.val_loss = {'batch':[], 'epoch':[]}\n",
    "        self.val_acc = {'batch':[], 'epoch':[]}\n",
    "\n",
    "    def on_batch_end(self, batch, logs={}):\n",
    "        self.losses['batch'].append(logs.get('loss'))\n",
    "        self.accuracy['batch'].append(logs.get('acc'))\n",
    "        self.val_loss['batch'].append(logs.get('val_loss'))\n",
    "        self.val_acc['batch'].append(logs.get('val_acc'))\n",
    "\n",
    "    def on_epoch_end(self, batch, logs={}):\n",
    "        self.losses['epoch'].append(logs.get('loss'))\n",
    "        self.accuracy['epoch'].append(logs.get('acc'))\n",
    "        self.val_loss['epoch'].append(logs.get('val_loss'))\n",
    "        self.val_acc['epoch'].append(logs.get('val_acc'))\n",
    "\n",
    "    def loss_plot(self, loss_type):\n",
    "        iters = range(len(self.losses[loss_type]))\n",
    "        plt.figure()\n",
    "        # acc\n",
    "        plt.plot(iters, self.accuracy[loss_type], 'r', label='train acc')\n",
    "        # loss\n",
    "        plt.plot(iters, self.losses[loss_type], 'g', label='train loss')\n",
    "        if loss_type == 'epoch':\n",
    "            # val_acc\n",
    "            plt.plot(iters, self.val_acc[loss_type], 'b', label='val acc')\n",
    "            # val_loss\n",
    "            plt.plot(iters, self.val_loss[loss_type], 'k', label='val loss')\n",
    "        plt.grid(True)\n",
    "        plt.xlabel(loss_type)\n",
    "        plt.ylabel('acc-loss')\n",
    "        plt.legend(loc=\"upper right\")\n",
    "        plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 建立模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "input_1 (InputLayer)         (None, 200, 12, 1)        0         \n",
      "_________________________________________________________________\n",
      "conv1 (Conv2D)               (None, 200, 12, 32)       1952      \n",
      "_________________________________________________________________\n",
      "pool1 (MaxPooling2D)         (None, 20, 12, 32)        0         \n",
      "_________________________________________________________________\n",
      "conv2 (Conv2D)               (None, 20, 12, 64)        18496     \n",
      "_________________________________________________________________\n",
      "pool2 (MaxPooling2D)         (None, 6, 6, 64)          0         \n",
      "_________________________________________________________________\n",
      "conv3 (Conv2D)               (None, 6, 6, 128)         73856     \n",
      "_________________________________________________________________\n",
      "pool3 (MaxPooling2D)         (None, 3, 3, 128)         0         \n",
      "_________________________________________________________________\n",
      "flatten (Flatten)            (None, 1152)              0         \n",
      "_________________________________________________________________\n",
      "dropout_1 (Dropout)          (None, 1152)              0         \n",
      "_________________________________________________________________\n",
      "fc1 (Dense)                  (None, 128)               147584    \n",
      "_________________________________________________________________\n",
      "dropout_2 (Dropout)          (None, 128)               0         \n",
      "_________________________________________________________________\n",
      "fc2 (Dense)                  (None, 49)                6321      \n",
      "=================================================================\n",
      "Total params: 248,209\n",
      "Trainable params: 248,209\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "def CNN(input_shape=(200,12,1), classes=49): \n",
    "    X_input = Input(input_shape)\n",
    "    \n",
    "    X = Conv2D(filters=32, kernel_size=(20,3), strides=(1,1),padding='same',activation='relu', name='conv1')(X_input)\n",
    "    X = MaxPooling2D((10,1), strides=(10,1), name='pool1')(X)\n",
    "\n",
    "    X = Conv2D(filters=64, kernel_size=(3,3), strides=(1,1),padding='same', activation='relu',name='conv2')(X)\n",
    "    X = MaxPooling2D((3,2), strides=(3,2), name='pool2')(X)\n",
    "    \n",
    "    X = Conv2D(filters=128, kernel_size=(3,3), strides=(1,1),padding='same', activation='relu',name='conv3')(X)\n",
    "    X = MaxPooling2D((2,2), strides=(2,2), name='pool3')(X)\n",
    "    \n",
    "    X = Flatten(name='flatten')(X)\n",
    "    X = Dropout(0.5)(X)\n",
    "    X = Dense(128,activation='relu',name='fc1')(X)\n",
    "    X = Dropout(0.5)(X)\n",
    "    X = Dense(classes, activation='softmax', name='fc2')(X)\n",
    "    \n",
    "    model = Model(inputs=X_input, outputs=X, name='CNN')\n",
    "    return model\n",
    "    \n",
    "model = CNN(input_shape = (200, 12, 1), classes = 49)\n",
    "model.summary()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 训练原始数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 13341 samples, validate on 3335 samples\n",
      "Epoch 1/100\n",
      "13341/13341 [==============================] - 24s 2ms/step - loss: 3.7859 - acc: 0.0443 - val_loss: 3.4416 - val_acc: 0.1301\n",
      "Epoch 2/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 3.2867 - acc: 0.1245 - val_loss: 2.6920 - val_acc: 0.2585\n",
      "Epoch 3/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 2.7382 - acc: 0.2212 - val_loss: 2.2332 - val_acc: 0.3742\n",
      "Epoch 4/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 2.3941 - acc: 0.3007 - val_loss: 1.9710 - val_acc: 0.4339\n",
      "Epoch 5/100\n",
      "13341/13341 [==============================] - 23s 2ms/step - loss: 2.1784 - acc: 0.3471 - val_loss: 1.8403 - val_acc: 0.4570\n",
      "Epoch 6/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 2.0190 - acc: 0.3855 - val_loss: 1.6799 - val_acc: 0.4867\n",
      "Epoch 7/100\n",
      "13341/13341 [==============================] - 23s 2ms/step - loss: 1.9141 - acc: 0.4093 - val_loss: 1.6404 - val_acc: 0.4999\n",
      "Epoch 8/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.8273 - acc: 0.4342 - val_loss: 1.5390 - val_acc: 0.5289\n",
      "Epoch 9/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.7503 - acc: 0.4454 - val_loss: 1.5003 - val_acc: 0.5319\n",
      "Epoch 10/100\n",
      "13341/13341 [==============================] - 23s 2ms/step - loss: 1.7053 - acc: 0.4686 - val_loss: 1.4847 - val_acc: 0.5337\n",
      "Epoch 11/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.6484 - acc: 0.4734 - val_loss: 1.4317 - val_acc: 0.5577\n",
      "Epoch 12/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.5976 - acc: 0.4913 - val_loss: 1.3839 - val_acc: 0.5697\n",
      "Epoch 13/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.5667 - acc: 0.5005 - val_loss: 1.3834 - val_acc: 0.5550\n",
      "Epoch 14/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.5197 - acc: 0.5079 - val_loss: 1.3495 - val_acc: 0.5721\n",
      "Epoch 15/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.4910 - acc: 0.5147 - val_loss: 1.3683 - val_acc: 0.5625\n",
      "Epoch 16/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.4832 - acc: 0.5192 - val_loss: 1.3361 - val_acc: 0.5760\n",
      "Epoch 17/100\n",
      "13341/13341 [==============================] - 23s 2ms/step - loss: 1.4420 - acc: 0.5279 - val_loss: 1.3101 - val_acc: 0.5871\n",
      "Epoch 18/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.4115 - acc: 0.5350 - val_loss: 1.2992 - val_acc: 0.5823\n",
      "Epoch 19/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.3863 - acc: 0.5476 - val_loss: 1.2722 - val_acc: 0.5898\n",
      "Epoch 20/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.3732 - acc: 0.5565 - val_loss: 1.2557 - val_acc: 0.5997\n",
      "Epoch 21/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.3428 - acc: 0.5593 - val_loss: 1.2498 - val_acc: 0.5958\n",
      "Epoch 22/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.3346 - acc: 0.5628 - val_loss: 1.2451 - val_acc: 0.6024\n",
      "Epoch 23/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.3177 - acc: 0.5690 - val_loss: 1.2570 - val_acc: 0.6015\n",
      "Epoch 24/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.2849 - acc: 0.5710 - val_loss: 1.2248 - val_acc: 0.6003\n",
      "Epoch 25/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.2858 - acc: 0.5745 - val_loss: 1.2366 - val_acc: 0.5937\n",
      "Epoch 26/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.2567 - acc: 0.5878 - val_loss: 1.2232 - val_acc: 0.6105\n",
      "Epoch 27/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.2325 - acc: 0.5843 - val_loss: 1.1999 - val_acc: 0.6132\n",
      "Epoch 28/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.2135 - acc: 0.5984 - val_loss: 1.2229 - val_acc: 0.6072\n",
      "Epoch 29/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.2012 - acc: 0.5965 - val_loss: 1.1920 - val_acc: 0.6219\n",
      "Epoch 30/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.1912 - acc: 0.6013 - val_loss: 1.2092 - val_acc: 0.6093\n",
      "Epoch 31/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.1871 - acc: 0.6039 - val_loss: 1.1882 - val_acc: 0.6261\n",
      "Epoch 32/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.1547 - acc: 0.6101 - val_loss: 1.1846 - val_acc: 0.6243\n",
      "Epoch 33/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.1601 - acc: 0.6074 - val_loss: 1.1839 - val_acc: 0.6129\n",
      "Epoch 34/100\n",
      "13341/13341 [==============================] - 23s 2ms/step - loss: 1.1309 - acc: 0.6170 - val_loss: 1.1785 - val_acc: 0.6225\n",
      "Epoch 35/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.1188 - acc: 0.6257 - val_loss: 1.1604 - val_acc: 0.6195\n",
      "Epoch 36/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.1128 - acc: 0.6281 - val_loss: 1.1676 - val_acc: 0.6216\n",
      "Epoch 37/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.1139 - acc: 0.6239 - val_loss: 1.1756 - val_acc: 0.6228\n",
      "Epoch 38/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.1062 - acc: 0.6302 - val_loss: 1.1755 - val_acc: 0.6246\n",
      "Epoch 39/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.0777 - acc: 0.6330 - val_loss: 1.1819 - val_acc: 0.6126\n",
      "Epoch 40/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.0882 - acc: 0.6325 - val_loss: 1.1642 - val_acc: 0.6264\n",
      "Epoch 41/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.0766 - acc: 0.6341 - val_loss: 1.1660 - val_acc: 0.6282\n",
      "Epoch 42/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.0674 - acc: 0.6401 - val_loss: 1.1713 - val_acc: 0.6222\n",
      "Epoch 43/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.0509 - acc: 0.6429 - val_loss: 1.1638 - val_acc: 0.6354\n",
      "Epoch 44/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.0447 - acc: 0.6439 - val_loss: 1.1782 - val_acc: 0.6171\n",
      "Epoch 45/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.0337 - acc: 0.6518 - val_loss: 1.1642 - val_acc: 0.6237\n",
      "Epoch 46/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.0466 - acc: 0.6412 - val_loss: 1.1506 - val_acc: 0.6276\n",
      "Epoch 47/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 1.0172 - acc: 0.6534 - val_loss: 1.1505 - val_acc: 0.6270\n",
      "Epoch 48/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.9842 - acc: 0.6684 - val_loss: 1.1731 - val_acc: 0.6237\n",
      "Epoch 49/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.9916 - acc: 0.6594 - val_loss: 1.1520 - val_acc: 0.6282\n",
      "Epoch 50/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.9844 - acc: 0.6647 - val_loss: 1.1511 - val_acc: 0.6339\n",
      "Epoch 51/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.9820 - acc: 0.6651 - val_loss: 1.1815 - val_acc: 0.6237\n",
      "Epoch 52/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.9666 - acc: 0.6706 - val_loss: 1.1671 - val_acc: 0.6270\n",
      "Epoch 53/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.9521 - acc: 0.6787 - val_loss: 1.1649 - val_acc: 0.6333\n",
      "Epoch 54/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.9563 - acc: 0.6754 - val_loss: 1.1741 - val_acc: 0.6369\n",
      "Epoch 55/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.9674 - acc: 0.6689 - val_loss: 1.1608 - val_acc: 0.6369\n",
      "Epoch 56/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.9583 - acc: 0.6752 - val_loss: 1.1889 - val_acc: 0.6261\n",
      "Epoch 57/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.9599 - acc: 0.6772 - val_loss: 1.1899 - val_acc: 0.6255\n",
      "Epoch 58/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.9301 - acc: 0.6850 - val_loss: 1.1776 - val_acc: 0.6273\n",
      "Epoch 59/100\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.9424 - acc: 0.6822 - val_loss: 1.1830 - val_acc: 0.6273\n",
      "Epoch 60/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.9268 - acc: 0.6826 - val_loss: 1.1610 - val_acc: 0.6387\n",
      "Epoch 61/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.9129 - acc: 0.6886 - val_loss: 1.1698 - val_acc: 0.6321\n",
      "Epoch 62/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.9218 - acc: 0.6883 - val_loss: 1.2046 - val_acc: 0.6204\n",
      "Epoch 63/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8957 - acc: 0.6931 - val_loss: 1.1755 - val_acc: 0.6288\n",
      "Epoch 64/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.9032 - acc: 0.6928 - val_loss: 1.1839 - val_acc: 0.6234\n",
      "Epoch 65/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8980 - acc: 0.6946 - val_loss: 1.1786 - val_acc: 0.6300\n",
      "Epoch 66/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.9068 - acc: 0.6883 - val_loss: 1.1642 - val_acc: 0.6345\n",
      "Epoch 67/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8689 - acc: 0.7008 - val_loss: 1.1816 - val_acc: 0.6381\n",
      "Epoch 68/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8848 - acc: 0.6943 - val_loss: 1.1756 - val_acc: 0.6327\n",
      "Epoch 69/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8619 - acc: 0.7069 - val_loss: 1.1940 - val_acc: 0.6333\n",
      "Epoch 70/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8588 - acc: 0.7077 - val_loss: 1.1737 - val_acc: 0.6252\n",
      "Epoch 71/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8501 - acc: 0.7129 - val_loss: 1.1902 - val_acc: 0.6315\n",
      "Epoch 72/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8713 - acc: 0.7035 - val_loss: 1.1584 - val_acc: 0.6351\n",
      "Epoch 73/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8530 - acc: 0.7107 - val_loss: 1.1813 - val_acc: 0.6369\n",
      "Epoch 74/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8335 - acc: 0.7114 - val_loss: 1.1689 - val_acc: 0.6444\n",
      "Epoch 75/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8446 - acc: 0.7149 - val_loss: 1.1930 - val_acc: 0.6309\n",
      "Epoch 76/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8481 - acc: 0.7087 - val_loss: 1.1920 - val_acc: 0.6297\n",
      "Epoch 77/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8459 - acc: 0.7153 - val_loss: 1.1759 - val_acc: 0.6399\n",
      "Epoch 78/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8242 - acc: 0.7170 - val_loss: 1.1832 - val_acc: 0.6414\n",
      "Epoch 79/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8403 - acc: 0.7137 - val_loss: 1.1913 - val_acc: 0.6312\n",
      "Epoch 80/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8323 - acc: 0.7200 - val_loss: 1.2113 - val_acc: 0.6339\n",
      "Epoch 81/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8292 - acc: 0.7159 - val_loss: 1.1715 - val_acc: 0.6390\n",
      "Epoch 82/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8166 - acc: 0.7202 - val_loss: 1.1898 - val_acc: 0.6291\n",
      "Epoch 83/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8321 - acc: 0.7176 - val_loss: 1.2038 - val_acc: 0.6348\n",
      "Epoch 84/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.7953 - acc: 0.7257 - val_loss: 1.2001 - val_acc: 0.6471\n",
      "Epoch 85/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.7931 - acc: 0.7305 - val_loss: 1.1834 - val_acc: 0.6303\n",
      "Epoch 86/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.8077 - acc: 0.7253 - val_loss: 1.2247 - val_acc: 0.6270\n",
      "Epoch 87/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.7883 - acc: 0.7322 - val_loss: 1.2123 - val_acc: 0.6303\n",
      "Epoch 88/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.7896 - acc: 0.7289 - val_loss: 1.2090 - val_acc: 0.6303\n",
      "Epoch 89/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.7973 - acc: 0.7322 - val_loss: 1.2182 - val_acc: 0.6327\n",
      "Epoch 90/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.7991 - acc: 0.7287 - val_loss: 1.2301 - val_acc: 0.6360\n",
      "Epoch 91/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.7992 - acc: 0.7309 - val_loss: 1.2091 - val_acc: 0.6351\n",
      "Epoch 92/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.7961 - acc: 0.7308 - val_loss: 1.2089 - val_acc: 0.6354\n",
      "Epoch 93/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.7861 - acc: 0.7308 - val_loss: 1.2322 - val_acc: 0.6342\n",
      "Epoch 94/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.7795 - acc: 0.7332 - val_loss: 1.2229 - val_acc: 0.6309\n",
      "Epoch 95/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.7637 - acc: 0.7394 - val_loss: 1.2012 - val_acc: 0.6378\n",
      "Epoch 96/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.7839 - acc: 0.7348 - val_loss: 1.2325 - val_acc: 0.6306\n",
      "Epoch 97/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.7707 - acc: 0.7365 - val_loss: 1.2565 - val_acc: 0.6294\n",
      "Epoch 98/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.7653 - acc: 0.7356 - val_loss: 1.2831 - val_acc: 0.6249\n",
      "Epoch 99/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.7536 - acc: 0.7449 - val_loss: 1.2401 - val_acc: 0.6384\n",
      "Epoch 100/100\n",
      "13341/13341 [==============================] - 22s 2ms/step - loss: 0.7635 - acc: 0.7431 - val_loss: 1.1938 - val_acc: 0.6360\n",
      "13341/13341 [==============================] - 4s 318us/step\n",
      "Train Loss = 0.28163469261283525\n",
      "Train Accuracy = 0.940259350850909\n",
      "3335/3335 [==============================] - 1s 316us/step\n",
      "Test Loss = 1.1937735625828938\n",
      "Test Accuracy = 0.6359820090312471\n",
      "time: 2225.586738586426\n"
     ]
    }
   ],
   "source": [
    "import time\n",
    "start = time.time()\n",
    "\n",
    "model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\n",
    "\n",
    "history = LossHistory() # 创建一个history实例\n",
    "\n",
    "model.fit(X_train, Y_train, epochs=100, batch_size=64, verbose=1, \n",
    "            validation_data=(X_test, Y_test),callbacks=[history])\n",
    "\n",
    "preds_train = model.evaluate(X_train, Y_train)\n",
    "print(\"Train Loss = \" + str(preds_train[0]))\n",
    "print(\"Train Accuracy = \" + str(preds_train[1]))\n",
    "\n",
    "preds_test  = model.evaluate(X_test, Y_test)\n",
    "print(\"Test Loss = \" + str(preds_test[0]))\n",
    "print(\"Test Accuracy = \" + str(preds_test[1]))\n",
    "\n",
    "end = time.time()\n",
    "print(\"time:\",end-start)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7efc5371a278>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "history.loss_plot('epoch')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  },
  "toc": {
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": "block",
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
